package com.example.onlinemonitoring.controller;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.example.onlinemonitoring.model.Dlqjcsensor;
import com.example.onlinemonitoring.Util.CommPortManager;
import com.example.onlinemonitoring.autoRun.ComRunner;
import com.example.onlinemonitoring.comCenter.DlqjcCom;
import com.example.onlinemonitoring.model.Appdevice;
import com.example.onlinemonitoring.model.Dlqjchistory;
import com.example.onlinemonitoring.model.DlqjcsensorTest;
import com.example.onlinemonitoring.model.common.MyResult;
import com.example.onlinemonitoring.model.common.chartres;
import com.example.onlinemonitoring.model.common.pagebase;
import com.example.onlinemonitoring.query.QueryObject;
import com.example.onlinemonitoring.serviceImpl.AppdeviceServiceImpl;
import com.example.onlinemonitoring.serviceImpl.DlqjcsensorServiceImpl;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import tk.mybatis.mapper.entity.Example;

import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import org.apache.poi.ss.usermodel.Workbook;

/**
 * Controller
 * 该部分代码为自动生成，请勿随意修改
 * 如有改动请删除该注释
 *
 * @author little pig page
 * @date 2022-03-28
 */
@Api(value = "断路器功能", tags = { "断路器设备接口" })
@RestController
@RequestMapping("/circuitbreaker")
public class DlqjcsensorController {
    Logger logger = LogManager.getLogger(LogManager.ROOT_LOGGER_NAME);
    @Autowired
    DlqjcsensorServiceImpl dlqjcsensorServiceImpl;
    @Autowired
    AppdeviceServiceImpl appdeviceimpl;

    @ApiOperation(value = "查询断路器实时曲线图", notes = "查询断路器实时曲线图")
    @ResponseBody
    @GetMapping("/selectSensorCurve")
    public MyResult<Float[][]> selectSensorCurve(
            @RequestParam(value = "stationid", required = true) Integer stationid,
            @RequestParam(value = "devicegroup", required = true) Integer devicegroup,
            @RequestParam(value = "deviceaddr", required = true) Integer deviceaddr,
            @RequestParam(value = "cmd", required = false) Integer cmd,
            @RequestParam(value = "laststate", required = true) Integer laststate) {
        Dlqjcsensor record = new Dlqjcsensor();
        record.setStationid(stationid);
        record.setDevicegroup(devicegroup);
        record.setDeviceaddr(deviceaddr);
        record.setCmd(cmd);
        record.setLaststate(laststate);
        return dlqjcsensorServiceImpl.selectdlqcurve(record);
    }

    @ApiOperation(value = "断路器波形图描述", notes = "断路器波形图描述")
    @ResponseBody
    @GetMapping("/selectWaveDescription")
    public MyResult<Integer> selectWaveDescription(
            @RequestParam(value = "stationid", required = false) Integer stationid,
            @RequestParam(value = "devicegroup", required = false) Integer devicegroup,
            @RequestParam(value = "deviceaddr", required = false) Integer deviceaddr,
            @RequestParam(value = "laststate", required = false) Integer laststate) {
        Dlqjcsensor record = new Dlqjcsensor();
        record.setStationid(stationid);
        record.setDeviceaddr(deviceaddr);
        record.setDevicegroup(devicegroup);
        record.setLaststate(laststate);
        return dlqjcsensorServiceImpl.selectChangedWave(record);
    }

    @ApiOperation(value = "根据id查找断路器曲线图2", notes = "根据id查找断路器曲线图2")
    @ResponseBody
    @GetMapping("/selectCurveById")
    public MyResult<Float[][]> selectCurveById(@RequestParam(value = "id", required = false) Long id) {
        Dlqjchistory record = new Dlqjchistory();
        record.setId(id);
        return dlqjcsensorServiceImpl.selectdlqhiscurve(record);
    }

    @ApiOperation(value = "根据LastState分组查询断路器历史表", notes = "根据LastState分组查询断路器历史表")
    @ResponseBody
    @GetMapping("/selectDeviceGroupByLastState")
    public MyResult<Dlqjchistory> selectDeviceGroupByLastState(
            @RequestParam(value = "stationid", required = false) Integer stationid,
            @RequestParam(value = "devicegroup", required = false) Integer devicegroup,
            @RequestParam(value = "deviceaddr", required = false) Integer deviceaddr,
            @RequestParam(value = "cmd", required = false) Integer cmd,
            @RequestParam(value = "begintime", required = false) String begintime,
            @RequestParam(value = "endtime", required = false) String endtime) {
        Dlqjchistory record = new Dlqjchistory();
        record.setStationid(stationid);
        record.setDeviceaddr(deviceaddr);
        record.setDevicegroup(devicegroup);
        record.setCmd(cmd);
        return dlqjcsensorServiceImpl.selectdlqhisgroupbystate(record, begintime, endtime);
    }

    @ApiOperation(value = "更新断路器标准数据", notes = "更新断路器标准数据")
    @ResponseBody
    @RequestMapping(value = "/updateDlqtest", method = RequestMethod.POST, produces = "application/json;charset=UTF-8")
    public MyResult<Integer> updateDlqtest(@RequestBody String jsonParam,
            @RequestParam(value = "stationid", required = false) Integer stationid,
            @RequestParam(value = "devicegroup", required = false) Integer devicegroup,
            @RequestParam(value = "deviceaddr", required = false) Integer deviceaddr) {
        JSONArray json = JSONArray.parseArray(jsonParam);
        DlqjcsensorTest record = new DlqjcsensorTest();
        for (int i = 0; i < json.size(); i++) {
            JSONObject object = (JSONObject) json.get(i);
            record.setDeviceaddr(deviceaddr);
            record.setStationid(stationid);
            record.setDevicegroup(devicegroup);
            record.setLaststate(object.getInteger("laststate"));
            record.setLasti0current(object.getFloat("i0current"));
            record.setLasti1current(object.getFloat("i1current"));
            record.setLasti2current(object.getFloat("i2current"));
            record.setLasti3current(object.getFloat("i3current"));
            record.setLasti4current(object.getFloat("i4current"));
            record.setLasti5current(object.getFloat("i5current"));
            record.setLastt0time(object.getInteger("t0time"));
            record.setLastt1time(object.getInteger("t1time"));
            record.setLastt2time(object.getInteger("t2time"));
            record.setLastt3time(object.getInteger("t3time"));
            record.setLastt4time(object.getInteger("t4time"));
            record.setLastt5time(object.getInteger("t5time"));
            dlqjcsensorServiceImpl.updatedlqtest(record);
        }
        if (json.size() == 3) {
            record.setDeviceaddr(deviceaddr);
            record.setStationid(stationid);
            record.setDevicegroup(devicegroup);
            record.setLaststate(3);
            record.setLasti0current(0f);
            record.setLasti1current(0f);
            record.setLasti2current(0f);
            record.setLasti3current(0f);
            record.setLasti4current(0f);
            record.setLasti5current(0f);
            record.setLastt0time(0);
            record.setLastt1time(0);
            record.setLastt2time(0);
            record.setLastt3time(0);
            record.setLastt4time(0);
            record.setLastt5time(0);
            dlqjcsensorServiceImpl.updatedlqtest(record);
        }
        MyResult<Integer> m = new MyResult<Integer>();
        m.setMsg("修改成功");
        m.setCode(0);
        return m;
    }

    @ApiOperation(value = "修改设备参数", notes = "修改设备参数")
    @ResponseBody
    @RequestMapping(value = "/updateAll", method = RequestMethod.POST, produces = "application/json;charset=UTF-8")
    public MyResult<Integer> updateAll(@RequestBody String jsonParam,
            @RequestParam(value = "stationid", required = false) Integer stationid,
            @RequestParam(value = "deviceaddr", required = false) Integer deviceaddr,
            @RequestParam(value = "devicegroup", required = false) Integer devicegroup) {
        JSONObject object = JSONObject.parseObject(jsonParam);
        Dlqjcsensor record = object.toJavaObject(Dlqjcsensor.class);
        MyResult<Integer> m = new MyResult<Integer>();
        record.setStationid(stationid);
        record.setDevicegroup(devicegroup);
        record.setDeviceaddr(deviceaddr);
        if (dlqjcsensorServiceImpl.Update(record, false) >= 1) {
            m.setMsg("修改成功");
            m.setCode(0);
        } else {
            m.setMsg("修改失败");
            m.setCode(1);
        }
        return m;
    }

    @ApiOperation(value = "修改设备报警", notes = "修改设备报警")
    @ResponseBody
    @RequestMapping(value = "/updateAlarm", method = RequestMethod.POST, produces = "application/json;charset=UTF-8")
    public MyResult<Integer> updateAlarm(@RequestBody String jsonParam,
            @RequestParam(value = "stationid", required = false) Integer stationid,
            @RequestParam(value = "deviceaddr", required = false) Integer deviceaddr,
            @RequestParam(value = "devicegroup", required = false) Integer devicegroup) {
        JSONObject object = JSONObject.parseObject(jsonParam);
        MyResult<Integer> m = new MyResult<Integer>();
        Dlqjcsensor record = object.toJavaObject(Dlqjcsensor.class);
        record.setStationid(stationid);
        record.setDevicegroup(devicegroup);
        record.setDeviceaddr(deviceaddr);
        if (dlqjcsensorServiceImpl.Update(record, false) >= 1) {
            m.setMsg("修改成功");
            m.setCode(0);
        } else {
            m.setMsg("修改失败");
            m.setCode(1);
        }
        return m;
    }

    @ApiOperation(value = "查询实时表数据", notes = "查询实时表数据")
    @ResponseBody
    @GetMapping("/selectSensorData")
    public MyResult<Dlqjcsensor> selectSensorData(
            @RequestParam(value = "page", required = false) Integer page,
            @RequestParam(value = "limit", required = false) Integer limit,
            @RequestParam(value = "stationid", required = false) Integer stationid,
            @RequestParam(value = "deviceaddr", required = false) Integer deviceaddr,
            @RequestParam(value = "devicegroup", required = false) Integer devicegroup,
            @RequestParam(value = "cmd", required = false) Integer cmd) {
        Dlqjcsensor record = new Dlqjcsensor();
        record.setStationid(stationid);
        record.setDeviceaddr(deviceaddr);
        record.setDevicegroup(devicegroup);
        record.setCmd(cmd);
        QueryObject qo = new QueryObject(page, limit);
        return dlqjcsensorServiceImpl.getList(record, qo);
    }

    @ApiOperation(value = "修改监测点名称", notes = "修改监测点名称")
    @ResponseBody
    @RequestMapping(value = "/updateMonitorName", method = RequestMethod.POST, produces = "application/json;charset=UTF-8")
    public MyResult<Integer> updateMonitorName(@RequestBody String jsonParam,
            @RequestParam(value = "stationid", required = true) Integer stationid,
            @RequestParam(value = "deviceaddr", required = true) Integer deviceaddr,
            @RequestParam(value = "devicegroup", required = true) Integer devicegroup) {
        JSONObject object = JSONObject.parseObject(jsonParam);
        MyResult<Integer> m = new MyResult<Integer>();
        Example example = new Example(Dlqjcsensor.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("stationid", stationid);
        criteria.andEqualTo("deviceaddr", deviceaddr);
        criteria.andEqualTo("devicegroup", devicegroup);
        Dlqjcsensor record = new Dlqjcsensor();
        record.setPointname(object.getString("pointname"));
        if (dlqjcsensorServiceImpl.updateByExampleSelective(record, example) >= 1) {
            m.setMsg("修改成功");
            m.setCode(0);
        } else {
            m.setMsg("修改失败");
            m.setCode(1);
        }
        return m;
    }

    @ApiOperation(value = "查询历史表数据", notes = "查询历史表数据")
    @ResponseBody
    @GetMapping("/selectHistoryData")
    public MyResult<Dlqjchistory> selectHistoryData(
            @RequestParam(value = "page", required = true) Integer page,
            @RequestParam(value = "limit", required = true) Integer limit,
            @RequestParam(value = "stationid", required = false) Integer stationid,
            @RequestParam(value = "deviceaddr", required = false) Integer deviceaddr,
            @RequestParam(value = "devicegroup", required = false) Integer devicegroup,
            @RequestParam(value = "start", required = false) String begintime,
            @RequestParam(value = "end", required = false) String endtime,
            @RequestParam(value = "pagecount", required = false) Integer pagecount) {
        Dlqjchistory record = new Dlqjchistory();
        record.setStationid(stationid);
        record.setDeviceaddr(deviceaddr);
        record.setDevicegroup(devicegroup);
        pagebase pagebase = new pagebase();
        pagebase.setBegintime(begintime);
        pagebase.setEndtime(endtime);
        pagebase.setPage(page);
        pagebase.setLimit(limit);
        pagebase.setPagecount(pagecount);
        return dlqjcsensorServiceImpl.getHisList(record, pagebase);
    }

    @ApiOperation(value = "查询历史表曲线", notes = "查询历史表曲线")
    @ResponseBody
    @GetMapping("/selectHistoryCurve")
    public MyResult<Float[][]> selectHistoryCurve(
            @RequestParam(value = "page", required = false) Integer page,
            @RequestParam(value = "limit", required = false) Integer limit,
            @RequestParam(value = "stationid", required = false) Integer stationid,
            @RequestParam(value = "deviceaddr", required = false) Integer deviceaddr,
            @RequestParam(value = "devicegroup", required = false) Integer devicegroup,
            @RequestParam(value = "start", required = false) String begintime,
            @RequestParam(value = "end", required = false) String endtime,
            @RequestParam(value = "pagecount", required = false) Integer pagecount,
            @RequestParam(value = "lstr", required = false) String lstr) {
        Dlqjchistory record = new Dlqjchistory();
        record.setStationid(stationid);
        record.setDeviceaddr(deviceaddr);
        record.setDevicegroup(devicegroup);
        pagebase pagebase = new pagebase();
        pagebase.setBegintime(begintime);
        pagebase.setEndtime(endtime);
        if (page != null) {
            pagebase.setPage((page - 1) * limit);
            pagebase.setLimit(limit);
        }
        pagebase.setPagecount(pagecount);
        pagebase.setIsasc(true);
        return dlqjcsensorServiceImpl.selectdlqhistorydatacurve(record, pagebase);
    }

    @ApiOperation(value = "断路器控制", notes = "断路器控制")
    @ResponseBody
    @GetMapping("/cmdDevice")
    public MyResult<String> cmdDevice(
            @RequestParam(value = "stationid", required = true) Integer stationid,
            @RequestParam(value = "devicegroup", required = true) Integer devicegroup,
            @RequestParam(value = "deviceaddr", required = true) Integer deviceaddr,
            @RequestParam(value = "trip", required = true) Integer trip,
            @RequestParam(value = "od", required = true) Integer od) {
        Appdevice record = new Appdevice();
        Example example = new Example(Appdevice.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("stationid", stationid);
        criteria.andEqualTo("devicegroup", devicegroup);
        criteria.andEqualTo("simple", "dlqjc");
        record = appdeviceimpl.selectOneByExample(example);
        int index = 0;
        DlqjcCom oc = null;
        switch (record.getCommunicationmode()) {
            case 1:
                index = CommPortManager.strGetNum(record.getCom());
                oc = (DlqjcCom) ComRunner.devmap.get(index);
                break;
            case 2:
                index = record.getId();
                oc = (DlqjcCom) ComRunner.netmap.get(index);
                break;
            case 3:
                index = record.getId();
                oc = (DlqjcCom) ComRunner.netservermap.get(index);
                break;
            default:
                break;
        }
        if (oc == null) {
            return new MyResult<String>(1, "断路器未开启！");
        }
        MyResult<String> res = new MyResult<>();
        oc.setIsrun(false);
        try {
            Thread.sleep(oc.getTimeout());
        } catch (InterruptedException e) {
            e.printStackTrace();
        } // 等待缓冲区完全释放
        try {
            // 每次发送控制之前就清空返回
            oc.setControllerRet("");
            oc.Send("7E018042" + String.format("%02x", trip) + String.format("%02x", od) + "0305");
            // 设置超时时间3s
            Long timestamp = System.currentTimeMillis() + 1000 * 3;
            while (System.currentTimeMillis() < timestamp) {
                if (!oc.getControllerRet().equals("")) {
                    List<String> l = new ArrayList<String>();
                    l.add(oc.getControllerRet());
                    // 保存到数据库
                    Dlqjcsensor dlq = new Dlqjcsensor();
                    dlq.setStationid(stationid);
                    dlq.setDevicegroup(devicegroup);
                    dlq.setDeviceaddr(deviceaddr);
                    dlq.setTrip(trip);
                    dlq.setOd(od);
                    if (dlqjcsensorServiceImpl.Update(dlq, false) >= 1) {
                        res.setMsg("操作成功！");
                        res.setCode(0);
                    } else {
                        res.setMsg("下位机已修改成功，但数据库保存失败");
                        res.setCode(1);
                    }
                    return res;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            oc.setIsrun(true);
        }
        res.setCode(1);
        res.setMsg("操作失败！");
        return res;
    }

    /**
     * 导出Excel
     */
    @GetMapping("exportToExcel")
    public void exportToExcel(HttpServletResponse response,
            @RequestParam(value = "stationid", required = true) Integer stationid,
            @RequestParam(value = "devicegroup", required = true) Integer devicegroup,
            @RequestParam(value = "deviceaddr", required = true) Integer deviceaddr,
            @RequestParam(value = "start", required = false) String begintime,
            @RequestParam(value = "end", required = false) String endtime) throws IOException {
        Dlqjchistory record = new Dlqjchistory();
        record.setStationid(stationid);
        record.setDeviceaddr(deviceaddr);
        record.setDevicegroup(devicegroup);
        pagebase pagebase = new pagebase();
        pagebase.setBegintime(begintime);
        pagebase.setEndtime(endtime);
        Workbook wb = dlqjcsensorServiceImpl.writeToExcelByList(record, pagebase);
        OutputStream output = response.getOutputStream();
        String fileName = "data.xlsx";
        try {
            fileName = URLEncoder.encode(fileName, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        response.setHeader("Content-disposition",
                "attachment;filename=" + fileName + ";" + "filename*=utf-8''" + fileName);
        wb.write(output);
        output.close();
    }

    /**
     * 导出Excel
     */
    @GetMapping("exportToSensorExcel")
    public void exportToSensorExcel(HttpServletResponse response,
            @RequestParam(value = "stationid", required = false) Integer stationid,
            @RequestParam(value = "devicegroup", required = false) Integer devicegroup,
            @RequestParam(value = "deviceaddr", required = false) Integer deviceaddr) throws IOException {
        Dlqjcsensor record = new Dlqjcsensor();
        record.setStationid(stationid);
        record.setDeviceaddr(deviceaddr);
        record.setDevicegroup(devicegroup);
        record.setCmd(67);
        Workbook wb = dlqjcsensorServiceImpl.writeToExcelBySensorList(record);
        OutputStream output = response.getOutputStream();
        String fileName = "data.xlsx";
        try {
            fileName = URLEncoder.encode(fileName, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        response.setHeader("Content-disposition",
                "attachment;filename=" + fileName + ";" + "filename*=utf-8''" + fileName);
        wb.write(output);
        output.close();
    }
}
